home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 1 Issue 2 / PDCD-1 - Issue 02.iso / _utilities / utilities / 003 / motorola / Sources / c / eval < prev    next >
Text File  |  1993-07-18  |  4KB  |  205 lines

  1. #include <stdio.h>
  2.  
  3. #include "mselect.h"    /*external selection of microprocessor symbol table*/
  4. #include "proto.h"
  5. #include "as.h"
  6. #include "structs.h"
  7. #include "extvars.h"
  8.  
  9.  
  10. /*
  11.  * eval --- evaluate expression
  12.  * 
  13.  * an expression is constructed like this:
  14.  * 
  15.  * expr ::=  expr + term | expr - term ; expr * term ; expr / term ; expr | term
  16.  * ; expr & term ; expr % term ; expr ^ term ;
  17.  * 
  18.  * term ::=  symbol | * | constant ;
  19.  * 
  20.  * symbol ::=  string of alphanumerics with non-initial digit
  21.  * 
  22.  * constant ::= hex constant | binary constant | octal constant | decimal
  23.  * constant | ascii constant;
  24.  * 
  25.  * hex constant ::= '$' {hex digits};
  26.  * 
  27.  * octal constant ::= '@' {octal digits};
  28.  * 
  29.  * binary constant ::= '%' { 1 | 0 };
  30.  * 
  31.  * decimal constant ::= {decimal digits};
  32.  * 
  33.  * ascii constant ::= ''' any printing char;
  34.  * 
  35.  */
  36. int
  37. eval(void)
  38. {
  39.     int             left, right;    /* left and right terms set
  40.                      * expression */
  41.     char            o;    /* operator character */
  42.  
  43. #ifdef DEBUG
  44.     printf("Evaluating %s\n", Optr);
  45. #endif
  46.     Force_byte = NO;
  47.     Force_word = NO;
  48.     if (*Optr == '<') {
  49.         Force_byte++;
  50.         Optr++;
  51.     } else if (*Optr == '>') {
  52.         Force_word++;
  53.         Optr++;
  54.     }
  55.     left = get_term();    /* pickup first part of expression */
  56.  
  57.     while (is_op(*Optr)) {
  58.         o = *Optr++;    /* pickup connector and skip */
  59.         right = get_term();    /* pickup current rightmost side */
  60.         switch (o) {
  61.         case '+':
  62.             left += right;
  63.             break;
  64.         case '-':
  65.             left -= right;
  66.             break;
  67.         case '*':
  68.             left *= right;
  69.             break;
  70.         case '/':
  71.             left /= right;
  72.             break;
  73.         case '|':
  74.             left |= right;
  75.             break;
  76.         case '&':
  77.             left &= right;
  78.             break;
  79.         case '%':
  80.             left %= right;
  81.             break;
  82.         case '^':
  83.             left = left ^ right;
  84.             break;
  85.         }
  86.     }
  87.  
  88.     Result = left;
  89. #ifdef DEBUG
  90.     printf("Result=%x\n", Result);
  91.     printf("Force_byte=%d  Force_word=%d\n", Force_byte, Force_word);
  92. #endif
  93.     return (YES);
  94. }
  95.  
  96. /*
  97.  * is_op --- is character an expression operator?
  98.  */
  99. int
  100. is_op(char c)
  101. {
  102.     if (any(c, "+-*/&%|^"))
  103.         return (YES);
  104.     return (NO);
  105. }
  106.  
  107.  
  108. /*
  109.  * get_term --- evaluate a single item in an expression
  110.  */
  111. int
  112. get_term(void)
  113. {
  114.     char            hold[MAXBUF];
  115.     char           *tmp;
  116.     int             val = 0;/* local value being built */
  117.     int             minus;    /* unary minus flag */
  118.     struct nlist   *pointer;
  119.     struct link    *pnt, *bpnt;
  120.  
  121.     if (*Optr == '-') {
  122.         Optr++;
  123.         minus = YES;
  124.     } else
  125.         minus = NO;
  126.  
  127.     while (*Optr == '#')
  128.         Optr++;
  129.  
  130.     /* look at rest of expression */
  131.  
  132.     if (*Optr == '%') {    /* binary constant */
  133.         Optr++;
  134.         while (any(*Optr, "01"))
  135.             val = (val * 2) + ((*Optr++) - '0');
  136.     } else if (*Optr == '@') {    /* octal constant */
  137.         Optr++;
  138.         while (any(*Optr, "01234567"))
  139.             val = (val * 8) + ((*Optr++) - '0');
  140.     } else if (*Optr == '$') {    /* hex constant */
  141.         Optr++;
  142.         while (any(*Optr, "0123456789abcdefABCDEF"))
  143.             if (*Optr > '9')
  144.                 val = (val * 16) + 10 + (mapdn(*Optr++) - 'a');
  145.             else
  146.                 val = (val * 16) + ((*Optr++) - '0');
  147.     } else if (any(*Optr, "0123456789")) {    /* decimal constant */
  148.         while (*Optr >= '0' && *Optr <= '9')
  149.             val = (val * 10) + ((*Optr++) - '0');
  150.     } else if (*Optr == '*') {    /* current location counter */
  151.         Optr++;
  152.         val = Old_pc;
  153.     } else if (*Optr == '\'') {    /* character literal */
  154.         Optr++;
  155.         if (*Optr == EOS)
  156.             val = 0;
  157.         else
  158.             val = *Optr++;
  159.     } else if (alpha(*Optr)) {    /* a symbol */
  160.         tmp = hold;    /* collect symbol name */
  161.         while (alphan(*Optr))
  162.             *tmp++ = *Optr++;
  163.         *tmp = EOS;
  164.         pointer = lookup(hold);
  165.         if (pointer != NULL) {
  166.             if (Pass == 2) {
  167.                 pnt = pointer->L_list;
  168.                 bpnt = NULL;
  169.                 while (pnt != NULL) {
  170.                     bpnt = pnt;
  171.                     pnt = pnt->next;
  172.                 }
  173.                 pnt = (struct link *) alloc(sizeof(struct link));
  174.                 if (bpnt == NULL)
  175.                     pointer->L_list = pnt;
  176.                 else
  177.                     bpnt->next = pnt;
  178.                 pnt->L_num = Line_num;
  179.                 pnt->next = NULL;
  180.             }
  181.             val = Last_sym;
  182.         } else {
  183.             if (Pass == 1) {    /* forward ref here */
  184.                 fwdmark();
  185.                 if (!Force_byte)
  186.                     Force_word++;
  187.                 val = 0;
  188.             } else    /* added ver TER_2.0  2 Jul 89 */
  189.                 error("Symbol undefined Pass 2");
  190.         }
  191.         if (Pass == 2 && Line_num == F_ref && Cfn == Ffn) {
  192.             if (!Force_byte)
  193.                 Force_word++;
  194.             fwdnext();
  195.         }
  196.     } else
  197.         /* none of the above */
  198.         val = 0;
  199.  
  200.     if (minus)
  201.         return (-val);
  202.     else
  203.         return (val);
  204. }
  205.